/* eslint-disable no-console */
/* eslint-disable class-methods-use-this */

/**
 *
 * ```ts
 * CodeFlow.new()
 *	.do(() => {
 *		tables.tables.forEach((table) => {
 *			const tableResult = this.getTableObject(table);
 *			if (tableResult) {
 *				results.push(tableResult);
 *			}
 *		});
 *	})
 *	.return("return", () => {
 *		return this.mergeObjectResult(results);
 *	});
 *
 *return CodeFlow.new()
 *	.forEach<InputTable>(tables.tables, (table) => {
 *		const tableResult = this.getTableObject(table);
 *		if (tableResult) {
 *			results.push(tableResult);
 *		}
 *	})
 *	.return("return", () => {
 *		return this.mergeObjectResult(results);
 *	});
 * ```
 */
export class CodeFlow {
	private pipeObj: any

	public do(func: () => void, descrition?: string): CodeFlow {
		console.log(descrition)
		func()
		return this
	}

	public forEach<T>(items: T[], func: (value: T, index: number, array: T[]) => void, descrition?: string): CodeFlow {
		console.log(descrition)
		items.forEach((value: T, index: number, array: T[]) => func(value, index, array))

		return this
	}

	public static new(): CodeFlow {
		return new CodeFlow()
	}

	public pipe<T, R>(descrition: string, func: (input: T) => R): CodeFlow {
		this.pipeObj = func(this.pipeObj as T)
		return this
	}

	public push<R>(descrition: string, func: () => R): CodeFlow {
		this.pipeObj = func()
		return this
	}

	public return<T>(descrition: string, func: () => T): T {
		console.log(descrition)
		return func()
	}
}
